﻿#include "page_o.h"
#include "ui_page_o.h"
#define n_max 20
#include <cmath>
#include <vector>

//================================ Виталий ================================
/*
В код включить все функции, кроме main (это пример их использования),
юзать закомментированные, третья функция используется в 1 из закомментированных
*/

/*!
 *param [in] n - кол-во элементов в выборке
 *param [in] p - вектор вероятностей событий
 *возвращаемое значение - ряд распределения для особого распределения (кол-во элементов в векторе = n+1)
 */
std::vector<double> special(int n, std::vector<double> &p);

/*!
 *param [in] ryad - ряд распределения геометрического, гипергеометрического или особого распределения
 *возвращаемое значение - математические характеристики:
 *	- мат. ожидание
 *	- дисперсия
 *	- средне квадратичное отклонение
 */
std::vector<double> mathCharacteristics(std::vector<double> &ryad);
void researchersError(int n, int k, std::vector<int> &chis, std::vector<double> &p, std::vector<double> &res);

std::vector<double> mathCharacteristics(std::vector<double> &ryad)
{
    std::vector<double> mathChar;
    double d, m = 0, m2 = 0;

    for (unsigned int i = 0; i < ryad.size(); i++)
    {
        m += i*ryad[i];
        m2 += i*i*ryad[i];
    }

    mathChar.push_back(m);
    d = m2 - m*m;
    mathChar.push_back(d);
    mathChar.push_back(sqrt(d));

    return mathChar;
}

std::vector<double> special(int n, std::vector<double> &p)
{
    std::vector<int> chis;
    std::vector<double> res;

    for (int i = 0; i < n; i++)
    {
        chis.push_back(0);
        res.push_back(0);
    }
    res.push_back(0);

    researchersError(n, 0, chis, p, res);

    return res;
}

void researchersError(int n, int k, std::vector<int> &chis, std::vector<double> &p, std::vector<double> &res)
{
    if (k < n)
        for (int i = 0; i < 2; i++)
        {
            chis[k] = i;
            researchersError(n, k+1, chis, p, res);
        }
    else
    {
        int m = 0;
        double sp = 1;
        for (int i = 0; i < n; i++)
        {
            m += chis[i];
            sp *= p[i]*chis[i] + (1-p[i])*(1 - chis[i]);
        }

        res[m] += sp;
    }
}

//========================================================================

page_o::page_o(QWidget *parent)
	: page_clean(parent)
{
	ui = new Ui::page_oClass();
	ui->setupUi(this);

    QObject::connect(ui->checkBox, SIGNAL(clicked(bool)), ui->checkBox_disp, SLOT(setChecked(bool)));
    QObject::connect(ui->checkBox, SIGNAL(clicked(bool)), ui->checkBox_f_raspr, SLOT(setChecked(bool)));
    QObject::connect(ui->checkBox, SIGNAL(clicked(bool)), ui->checkBox_sr_kv_otkl, SLOT(setChecked(bool)));
    QObject::connect(ui->checkBox, SIGNAL(clicked(bool)), ui->checkBox_math_o, SLOT(setChecked(bool)));
    QObject::connect(ui->checkBox, SIGNAL(clicked(bool)), ui->checkBox_rad_raspr, SLOT(setChecked(bool)));
}

page_o::~page_o()
{
    delete ui;
}

bool page_o::inputSpecial(unsigned int *n, std::vector<double> *p)
{
    (*n) = ui->input_n->value();
    p->clear();
    QStringList pistr = ui->input_pi->text().split(' ',QString::SkipEmptyParts);
    if(pistr.count() != (*n))
        return false;
    for(int i=0;i<pistr.count();++i)
    {
        p->push_back(pistr[i].toDouble());
    }
    return true;
}

void page_o::on_calc_btn_clicked()
{
    unsigned int n;
    std::vector<double> p;
    if(!inputSpecial(&n,&p))
    {
        emit appendToLog("неверные данные");
        return;
    }
    std::vector<double> v = special(n,p);
    std::vector<double> params = mathCharacteristics(v);
    if(ui->checkBox_rad_raspr->checkState()==Qt::Checked)
    {
        show_Rad(v);
    }
    if(ui->checkBox_math_o->checkState()==Qt::Checked)
    {
        emit appendToLog(QString("M(X) = ")+QString::number(params[0]));
    }
    if(ui->checkBox_disp->checkState()==Qt::Checked)
    {
        emit appendToLog(QString("D(X) = ")+QString::number(params[1]));
    }
    if(ui->checkBox_sr_kv_otkl->checkState()==Qt::Checked)
    {
        emit appendToLog(QString("&#963;(X) = ")+QString::number(params[2]));
    }
    if(ui->checkBox_f_raspr->checkState()==Qt::Checked)
    {
        show_Graph(v);
    }
    //if(ui->checkBox_mng->checkState()==Qt::Checked)           //calc_Mng();
    //if(ui->checkBox_graph->checkState()==Qt::Checked)
    emit appendToLog("<hr />");
}
